#pragma once
// ================== 包含头文件 ====================
#include <project_config.h>
#include <stm32f4xx_hal.h> // 确保包含必要的HAL头文件
// ================== 包含头文件结束 =================
#include <cstdint>
namespace hal::detail_dac
{
    class dac_config
    {

        static inline DAC_ChannelConfTypeDef sConfig = {0};
        static inline DAC_HandleTypeDef hdac;
        static inline DMA_HandleTypeDef hdma_dac1;
    // 硬件常量配置（移除static使用constexpr外部链接）
        constexpr static uint32_t default_channel = DAC_CHANNEL_1;  // 默认使用通道1
        constexpr static uint32_t default_align   = DAC_ALIGN_12B_R;// 默认数据对齐方式

    public:
        static void init()
        {
            // 1. 启用时钟
            __HAL_RCC_DAC_CLK_ENABLE();
            __HAL_RCC_GPIOA_CLK_ENABLE();

            // 2. 配置 GPIO 为模拟模式
            GPIO_InitTypeDef GPIO_InitStruct = {0};
            GPIO_InitStruct.Pin = GPIO_PIN_4;
            GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
            GPIO_InitStruct.Pull = GPIO_NOPULL;
            HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

            // 3. 初始化 DAC 基本配置
            hdac.Instance = DAC;
            HAL_DAC_Init(&hdac);

            // 4. 配置 DAC 通道 - 关键修改点！
            sConfig.DAC_Trigger = DAC_TRIGGER_NONE;      // 无外部触发
            sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; // 使能输出缓冲

            HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1);
            HAL_DAC_Start(&hdac, DAC_CHANNEL_1);         // 启动通道
        }


        static DAC_HandleTypeDef *getDACHandle() { return &hdac; }
        using dac_pin = hal::gpio::pinOld<GPIOA_BASE, GPIO_PIN_4>;

        /**
             * @brief 启动DAC输出
             * @param channel 目标通道
             */
        static void start(uint32_t channel=default_channel) noexcept
        {
            HAL_DAC_Start(&hdac, channel);
        }

        /**
             * @brief 停止DAC输出
             * @param channel 目标通道
             */
        static void stop(uint32_t channel =default_channel) noexcept
        {
            HAL_DAC_Stop(&hdac, channel);
        }

        /**
             * @brief 设置DAC输出值
             * @param value 12位右对齐数值 (0-4095)
             * @param channel 目标通道
             * @note 数值会根据对齐方式自动处理
             */
        static void set_value(uint16_t value,
                              uint32_t channel = default_channel) noexcept
        {
            HAL_DAC_SetValue(&hdac,
                             channel,
                             default_align,
                             value);
        }

        /**
             * @brief 设置输出电压（毫伏）
             * @param mv 输出电压值 (0-3300mV)
             * @param vref 参考电压值 (默认3.3V)
             * @return 实际设置的DAC数值
             */
        static uint16_t set_voltage(float mv, float vref = 3300.0f) noexcept
        {
            constexpr uint32_t max_dac = 0xFFF;// 12位最大值
            const float value = (mv / vref) * max_dac;
            const auto dac_value = static_cast<uint16_t>(value > max_dac ? max_dac : value);

            set_value(dac_value);
            return dac_value;
        }

    };

}